package com.whzjkj.gateway.server.tcp.handler;

import com.whzjkj.gateway.constant.JT808Constant;
import com.whzjkj.gateway.server.adapter.TerminalMessageProcessorAdapter;
import com.whzjkj.gateway.server.codce.JT808MessageDecoder;
import com.whzjkj.gateway.server.processor.TerminalMessageProcessor;
import com.whzjkj.gateway.server.session.TCPSessionManager;
import com.whzjkj.gateway.util.HexUtils;
import com.whzjkj.gateway.util.JT808ProtocolUtils;
import com.whzjkj.gateway.vo.PackageData;
import com.whzjkj.gateway.server.session.Session;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Slf4j
@Component
@ChannelHandler.Sharable
public class TCPServerHandler extends ChannelInboundHandlerAdapter {

	@Resource
	private TerminalMessageProcessorAdapter terminalMessageProcessor;
	@Resource
	private JT808MessageDecoder messageDecoder;
	@Resource
	private TCPSessionManager sessionManager;



	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		try {
			if (msg instanceof ByteBuf){
				ByteBuf buf = (ByteBuf) msg;

				if (buf.readableBytes() <= 0) {
					return;
				}

				byte[] tmp = new byte[buf.readableBytes()];
				buf.readBytes(tmp);
				//转译接收的消息
				byte[] bs = JT808ProtocolUtils.translationReceive(tmp);
				PackageData packageData = messageDecoder.byte2PackageData(bs);
				packageData.setChannel(ctx.channel());
				terminalMessageProcessor.processTerminalMessage(packageData);
				log.info(HexUtils.toHexString(bs));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			release(msg);
		}
	}


	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
		log.error("发生异常:{}", cause.getMessage());
		cause.printStackTrace();
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		Session session = Session.buildSession(ctx.channel());
		sessionManager.put(session.getId(), session);
		log.info("终端连接:{}", session);
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		final String sessionId = ctx.channel().id().asLongText();
		Session session = sessionManager.findBySessionId(sessionId);
		this.sessionManager.removeBySessionId(sessionId);
		log.info("终端断开连接:{}", session);
		ctx.channel().close();
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
			IdleStateEvent event = (IdleStateEvent) evt;
			if (event.state() == IdleState.READER_IDLE) {
				Session session = this.sessionManager.removeBySessionId(Session.buildId(ctx.channel()));
				log.error("服务器主动断开连接:{}", session);
				ctx.close();
			}
		}
	}

	private void release(Object msg) {
		try {
			ReferenceCountUtil.release(msg);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}